#include <QVector>

#include "heuristique.h"
#include "ia.h"

//sale!
#include "mapwidget.h"

class MoveCmd;

AB_M alphaBeta(int profondeur, GameMap &etat, float alpha, float beta, MoveCmd* mission)
{
    //qDebug() << "[AlphaBeta] ::" << profondeur;
    //MoveCmd v_mission;
    AB_M Best_M, val_M;
    Best_M.val = -9999;
    Best_M.mission = mission; //v_mission;
    val_M = Best_M;
    float val;
    GameMap* etat_n;

    Heuristique heuristique(QPoint(etat.cols(), etat.rows()));

    if ((profondeur < 1) || etat.isFinal())
    {
        Best_M.val = heuristique.compute(etat.allies(), etat.ennemies(), etat.targets());
        return Best_M;
    }

    std::vector<MoveCmd*> mission_A = IA::available(etat);

    if(mission_A.empty())
    {
        Best_M.val = heuristique.compute(etat.allies(), etat.ennemies(), etat.targets()); //todo
        return Best_M;
    }

    unsigned int Index;
    float Alpha_i, Beta_i;
    for (Index = 0; Index < mission_A.size(); Index++)
    {
        //Apply
        etat_n = new GameMap(etat);
        etat_n->update(mission_A[Index]);

        //debug visuel (a virer)
//        MapWidget* mwdg = new MapWidget();
//        mwdg->update(etat_n);
//        mwdg->setWindowTitle("A/B: "+QString::number(profondeur)+"; A:" +
//                             QString::number(alpha) +"; B:" +
//                             QString::number(beta) + " Index: " +
//                             QString::number(Index));
//        mwdg->show();
//        mwdg->resize(etat_n->cols()*20,etat.rows()*10);

        etat_n->invert(); // inversiooooon !
        Alpha_i = -beta;
        Beta_i = - alpha;
        val_M =  alphaBeta(profondeur-1, *etat_n, Alpha_i, Beta_i, mission_A[Index]);
        //Alpha = -Beta_i;
        //Beta = - Alpha_i; redondant !
        etat_n->invert(); // inversiooooon !
        val = -val_M.val;

        if (val > Best_M.val) {
            Best_M.val = val;
            Best_M.mission = mission_A[Index];
            if (val > alpha) {
                if (val >= beta) {
                    return Best_M;
                }
                alpha = val;
            }
        }
    }
    return Best_M;
}


//AB_M AlphaBeta(int profondeur, GameMap &etat, float &Alpha, float &Beta, std::vector<MoveCmd*> missions)
//{
//    //MoveCmd v_mission;
//    AB_M Best_M, val_M;
//    Best_M.val = -9999;
//    Best_M.mission = 0; //v_mission;
//    val_M = Best_M;
//    float val;
//    GameMap* etat_n;

//    if ((profondeur < 1) || etat.isFinal()) {
//        Best_M.val = Heuristique(etat);
//        return Best_M;
//    }

//    std::vector<MoveCmd*> mission_A = Available(etat, missions);

//    if (!(mission_A.size() > 0)) {
//        Best_M.val = Heuristique(etat);
//        return Best_M;
//    }

//    unsigned int Index;
//    float Alpha_i, Beta_i;
//    for (Index = 0; Index < mission_A.size(); Index++) {
//        //Apply
//        etat.update(mission_A[Index]);
//        etat_n = new GameMap(etat);
//        //Game::Invet();
//        Alpha_i = -Beta;
//        Beta_i = - Alpha;
//        val_M =  AlphaBeta(profondeur, *etat_n, Alpha_i, Beta_i, missions);
//        Alpha = -Beta_i;
//        Beta = - Alpha_i;
//        //Game::Invet();
//        val = -val_M.val;

//        if (val > Best_M.val) {
//            Best_M.val = val;
//            Best_M.mission = mission_A[Index];
//            if (val > Alpha) {
//                if (val >= Beta) {
//                    return Best_M;
//                }
//                Alpha = val;
//            }
//        }
//    }
//    return Best_M;
//}


